17. 电话号码的字母组合

17. 电话号码的字母组合

题目链接
代码随想录

分析

77. 组合 是从同一个集合 m 中取 n 个元素进行组合,m<n,且组合不能重复,而这道题是从 m 个不同的集合中取 m 个元素进行组合,每个集合取出来一个元素,不用考虑组合重复的问题,更简单。
方法是,循环来源字符串的每一个位置上的数字对应的所有可能即可,方法是用 for 循环嵌套,每一层 for 循环遍历的都是这个位置上的所有可能的情况。
我们直接用字符串数组来保存数字跟字符的映射关系,数字为索引,字符串为数字对应的所有字符的集合。
现在我们来讲一遍思路∶我们从来源字符串的第一个字符开始,index 为 0,在字符串数组中获取数字对应的字符串,for 遍历这个字符串中的所有字符,同时在 for 循环中进行递归调用,传入 index+1,表示处理来源字符串的下一个字符。
这里跟 77. 组合 有一个区别就是,因为我们遍历的是多个不同的集合,所以我们进行递归调用的时候,传入的是 index+1,而不是当前 for 循环的循环变量 i。

这里有两个优化的点:

解题

class Solution {

    public String[] numMap = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};

    public List<String> result = new ArrayList<>();

    public List<String> letterCombinations(String digits) {
        backTraceing(digits,0,new StringBuilder());
        return result;
    }

    public void backTraceing(String digits,int index,StringBuilder sb){
        if(index >= digits.length()){
            result.add(sb.toString());
            return;
        }
        char ele = digits.charAt(index);
        // 直接通过减去 '0' 这个字符,实际上是减去 '0' 的 ASCII 码来快速确定 int 值
        int eleInt = ele -'0';
        // 不能大于9,也不能小于0
        if(eleInt<0 || eleInt>9){
	        return;
        }
        char[] arr = numMap[eleInt].toCharArray();
        for(int i=0;i<arr.length;i++){
            int length = sb.length();
            sb.append(arr[i]);
            backTraceing(digits,index+1,sb);
            sb.setLength(length);
        }
    }
}

相关题

77. 组合
216. 组合总和 III